home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C/C++ Users Group Library 1996 July
/
C-C++ Users Group Library July 1996.iso
/
listings
/
v_08_12
/
8n12085a
< prev
next >
Wrap
Text File
|
1990-08-28
|
5KB
|
172 lines
/* kserver.c - task Keyboard Server interrupt driven */
#include <synrtx.h>
#include <ascii.h>
#define BEEP 8
#define NCHARS 80
#define NOBODY 0
#define EOI 0x20
static word buffer[NCHARS], nCharsIn, charToSend, charToReceive;
static task_t ksid, owner;
static msg_t msg;
/* handler numbers */
#define ACQUIRE 0
#define RELEASE 1
#define HIT 2
#define EXCEPTION 3
#define GETCHAR 4
#define PORT_A 0x60 /* 8255 */
#define PORT_B 0x61
static char kbdTab[] = {
NUL,ESC,'1','2','3','4','5','6','7','8','9','0','-','=', /* 00-13 */
BS,HT,'q','w','e','r','t','y','u','i','o','p','[',']',CR, /* 14-28 */
0,'a','s','d','f','g','h','j','k','l',';','\"','`', /* 29-41 */
0,'\\','z','x','c','v','b','n','m',',','.','/',0,'*', /* 34-55 */
0,' ',0 }; /* 56-58 */
static byte code, status;
static bool bufferFull;
/* Hardware handler Keyboard for interrupt vector 9 */
static handler Keyboard(void) {
/* disable keyboard interrupt to not overwrite interrupt stack */
dev_enable(DISABLE, 1, KEYBOARD);
cpu_enable(); /* allow further interrupts */
code = dev_byte(PORT_A);
status = dev_byte(PORT_B);
dev_setByte(status | 0x80, PORT_B); /* send ack _/^\_ to kbd */
dev_setByte(status & 0x7F, PORT_B);
if (code < 0x80 && kbdTab[code] && !bufferFull) {
msg.value.w = (word)kbdTab[code];
/* interrupt KeyboardServer.GetChar */
task_interrupt(&msg);
}
/* keep all interrupts disable for the EOI and Exit */
cpu_Disable();
dev_setByte(EOI, 0x20);
dev_enable(ENABLE, 1, KEYBOARD);
}
static handler Acquire(msg_t *msg_p) {
register task_t caller = msg_p->srcTid;
register task_t self = msg_p->dstTid;
owner = caller;
charToSend = charToReceive = nCharsIn = 0;
bufferFull = FALSE;
/* interrupt caller.Grant */
msg_p->srcTid = self;
msg_p->dstTid = caller;
msg_p->dstHid = 0; /* GRANT = 0 */
msg_p->type = msg_type_SYNC;
task_interrupt(msg_p);
}
static handler Release(msg_t *msg_p) {
register task_t caller = msg_p->srcTid;
register task_t self = msg_p->dstTid;
if (owner == caller) {
owner = NOBODY;
/* BufferFull is set to TRUE to avoid any software interrupts */
bufferFull = TRUE;
} else {
/* interrupt self.Exception(caller) */
msg_p->srcTid = msg_p->dstTid = self;
msg_p->dstHid = EXCEPTION;
msg_p->type = msg_type_WORD;
msg_p->value.w = (word)caller;
task_interrupt(msg_p);
}
}
static handler Hit(msg_t *msg_p) {
register task_t caller = msg_p->srcTid;
register task_t self = msg_p->dstTid;
register word c;
if (owner == caller) {
if (nCharsIn == 0) /* buffer empty ? */
c = 0;
else {
c = buffer[charToSend] | 0x0100;
charToSend = (charToSend + 1) % NCHARS;
nCharsIn--;
bufferFull = FALSE;
}
/* interrupt caller.GetChar(character) */
msg_p->srcTid = msg_p->dstTid;
msg_p->dstTid = caller;
msg_p->dstHid = 1; /* GetChar = 1 */
msg_p->type = msg_type_WORD;
msg_p->value.w = c;
task_interrupt(msg_p);
} else {
/* interrupt self.Exception(caller) */
msg_p->srcTid = msg_p->dstTid = self;
msg_p->dstHid = EXCEPTION;
msg_p->type = msg_type_WORD;
msg_p->value.w = (word)caller;
task_interrupt(msg_p);
}
}
static handler Exception(msg_t *msg_p) {
io_putf("Illegal Access to KeyboardServer by Task #%w", msg_p->value.w);
}
static handler GetChar(msg_t *msg_p) {
if (nCharsIn == NCHARS) /* buffer full ? */ {
/* then, ignore the character (stops int from hard) */
io_puts("\nKeyboardServer: buffer full !\n");
bufferFull = TRUE;
} else {
buffer[charToReceive] = msg_p->value.w;
charToReceive = (charToReceive + 1) % NCHARS;
nCharsIn++;
}
}
task KeyboardServer(void) {
register word ps;
ps = cpu_saveAndDisable();
ksid = task_self();
/* Install Keyboard hardware handler as the ISR for interrupt vector 9 */
cpu_setHandler(INT9_KEYBOARD, Keyboard);
/* Install software handlers */
task_setHandler(5, Acquire, Release, Hit, Exception, GetChar);
charToSend = charToReceive = nCharsIn = 0;
/*
* The KeyboardServer cannot receive characters while it is not yet
* acquired, but should wait until a "client" gets it.
* BufferFull is set to TRUE to avoid any software interrupts.
*/
bufferFull = TRUE;
msg.srcTid = msg.dstTid = ksid;
msg.dstHid = GETCHAR;
msg.type = msg_type_WORD;
cpu_restore(ps);
loop {
/* enable wait Acquire */
task_enableWait(NO_TIMEOUT, 1, ACQUIRE);
do /* enable wait GetChar, Hit, Release, Exception */
task_enableWait(NO_TIMEOUT,4,GETCHAR,HIT,RELEASE,EXCEPTION);
while (owner != NOBODY);
}
}